home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / fsusg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  7.8 KB  |  333 lines

  1. /* fsusage.c -- return space usage of mounted filesystems
  2.    Copyright (C) 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 2, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  17.  
  18.    This file was modified slightly by Ian Lance Taylor, December 1992,
  19.    and again July 1995, for use with Taylor UUCP.  */
  20.  
  21. #include "uucp.h"
  22. #include "uudefs.h"
  23. #include "sysdep.h"
  24. #include "fsusg.h"
  25.  
  26. int statfs ();
  27.  
  28. #if HAVE_SYS_PARAM_H
  29. #include <sys/param.h>
  30. #endif
  31.  
  32. #if HAVE_SYS_MOUNT_H
  33. #include <sys/mount.h>
  34. #endif
  35.  
  36. #if HAVE_SYS_VFS_H
  37. #include <sys/vfs.h>
  38. #endif
  39.  
  40. #if HAVE_SYS_FILSYS_H
  41. #include <sys/filsys.h>        /* SVR2.  */
  42. #endif
  43.  
  44. #if HAVE_FCNTL_H
  45. #include <fcntl.h>
  46. #endif
  47.  
  48. #if HAVE_SYS_STATFS_H
  49. #include <sys/statfs.h>
  50. #endif
  51.  
  52. #if HAVE_SYS_DUSTAT_H        /* AIX PS/2.  */
  53. #include <sys/dustat.h>
  54. #endif
  55.  
  56. #if HAVE_SYS_STATVFS_H        /* SVR4.  */
  57. #include <sys/statvfs.h>
  58. int statvfs ();
  59. #endif
  60.  
  61. #if HAVE_USTAT_H        /* SVR2 and others.  */
  62. #include <ustat.h>
  63. #endif
  64.  
  65. #if STAT_DISK_SPACE        /* QNX.  */
  66. #include <sys/disk.h>
  67. #include <errno.h>
  68. #endif
  69.  
  70. #define STAT_NONE 0
  71.  
  72. #if ! STAT_STATFS3_OSF1
  73. #if ! STAT_STATFS2_FS_DATA
  74. #if ! STAT_STATFS2_BSIZE
  75. #if ! STAT_STATFS2_FSIZE
  76. #if ! STAT_STATFS4
  77. #if ! STAT_STATVFS
  78. #if ! STAT_DISK_SPACE
  79. #if ! STAT_USTAT
  80. #undef STAT_NONE
  81. #define STAT_NONE 1
  82. #endif
  83. #endif
  84. #endif
  85. #endif
  86. #endif
  87. #endif
  88. #endif
  89. #endif
  90.  
  91. #if ! STAT_NONE
  92.  
  93. static long adjust_blocks P((long blocks, int fromsize, int tosize));
  94.  
  95. /* Return the number of TOSIZE-byte blocks used by
  96.    BLOCKS FROMSIZE-byte blocks, rounding away from zero.
  97.    TOSIZE must be positive.  Return -1 if FROMSIZE is not positive.  */
  98.  
  99. static long
  100. adjust_blocks (blocks, fromsize, tosize)
  101.      long blocks;
  102.      int fromsize, tosize;
  103. {
  104.   if (tosize <= 0)
  105.     abort ();
  106.   if (fromsize <= 0)
  107.     return -1;
  108.                                     
  109.   if (fromsize == tosize)    /* E.g., from 512 to 512.  */
  110.     return blocks;
  111.   else if (fromsize > tosize)    /* E.g., from 2048 to 512.  */
  112.     return blocks * (fromsize / tosize);
  113.   else                /* E.g., from 256 to 512.  */
  114.     return (blocks + (blocks < 0 ? -1 : 1)) / (tosize / fromsize);
  115. }
  116.  
  117. #endif
  118.  
  119. /* Fill in the fields of FSP with information about space usage for
  120.    the filesystem on which PATH resides.
  121.    DISK is the device on which PATH is mounted, for space-getting
  122.    methods that need to know it.
  123.    Return 0 if successful, -1 if not. */
  124.  
  125. int
  126. get_fs_usage (path, disk, fsp)
  127.      char *path, *disk;
  128.      struct fs_usage *fsp;
  129. {
  130. #if STAT_NONE
  131.   return -1;
  132. #endif
  133.  
  134. #if STAT_STATFS3_OSF1
  135.   struct statfs fsd;
  136.  
  137.   if (statfs (path, &fsd, sizeof (struct statfs)) != 0)
  138.     return -1;
  139. #define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_fsize, 512)
  140. #endif /* STAT_STATFS3_OSF1 */
  141.  
  142. #if STAT_STATFS2_FS_DATA    /* Ultrix.  */
  143.   struct fs_data fsd;
  144.  
  145.   if (statfs (path, &fsd) != 1)
  146.     return -1;
  147. #define CONVERT_BLOCKS(b) adjust_blocks ((long) (b), 1024, 512)
  148.   fsp->fsu_blocks = CONVERT_BLOCKS (fsd.fd_req.btot);
  149.   fsp->fsu_bfree = CONVERT_BLOCKS (fsd.fd_req.bfree);
  150.   fsp->fsu_bavail = CONVERT_BLOCKS (fsd.fd_req.bfreen);
  151.   fsp->fsu_files = fsd.fd_req.gtot;
  152.   fsp->fsu_ffree = fsd.fd_req.gfree;
  153. #endif
  154.  
  155. #if STAT_STATFS2_BSIZE        /* 4.3BSD, SunOS 4, HP-UX, AIX.  */
  156.   struct statfs fsd;
  157.  
  158.   if (statfs (path, &fsd) < 0)
  159.     return -1;
  160. #define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_bsize, 512)
  161. #endif
  162.  
  163. #if STAT_STATFS2_FSIZE        /* 4.4BSD.  */
  164.   struct statfs fsd;
  165.  
  166.   if (statfs (path, &fsd) < 0)
  167.     return -1;
  168. #define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_fsize, 512)
  169. #endif
  170.  
  171. #if STAT_STATFS4        /* SVR3, Dynix, Irix.  */
  172.   struct statfs fsd;
  173.  
  174.   if (statfs (path, &fsd, sizeof fsd, 0) < 0)
  175.     return -1;
  176.   /* Empirically, the block counts on most SVR3 and SVR3-derived
  177.      systems seem to always be in terms of 512-byte blocks,
  178.      no matter what value f_bsize has.  */
  179. # if _AIX
  180. #  define CONVERT_BLOCKS(b) adjust_blocks ((b), fsd.f_bsize, 512)
  181. # else
  182. #  define CONVERT_BLOCKS(b) (b)
  183. #  ifndef _SEQUENT_        /* _SEQUENT_ is DYNIX/ptx.  */
  184. #   ifndef DOLPHIN        /* DOLPHIN 3.8.alfa/7.18 has f_bavail */
  185. #    define f_bavail f_bfree
  186. #   endif
  187. #  endif
  188. # endif
  189. #endif
  190.  
  191. #if STAT_STATVFS        /* SVR4.  */
  192.   struct statvfs fsd;
  193.  
  194.   if (statvfs (path, &fsd) < 0)
  195.     return -1;
  196.   /* f_frsize isn't guaranteed to be supported.  */
  197. #define CONVERT_BLOCKS(b) \
  198.   adjust_blocks ((b), fsd.f_frsize ? fsd.f_frsize : fsd.f_bsize, 512)
  199. #endif
  200.  
  201. #if STAT_DISK_SPACE        /* QNX.  */
  202.   int o;
  203.   int iret;
  204.   long cfree_blocks, ctotal_blocks;
  205.   char *zpath;
  206.   char *zslash;
  207.     
  208.   zpath = zbufcpy (path);
  209.   while ((o = open (zpath, O_RDONLY, 0)) == -1
  210.      && errno == ENOENT)
  211.     {
  212.       /* The named file doesn't exist, so we can't open it.  Try the
  213.      directory containing it. */
  214.       if ((strcmp ("/", zpath) == 0)
  215.       || (strcmp (zpath, ".") == 0)
  216.       || (strcmp (zpath, "") == 0)
  217.       /* QNX peculiarity: "//2" means root on node 2 */
  218.       || ((strncmp (zpath, "//", 2) == 0)
  219.           && (strchr (zpath + 2, '/') == NULL)))
  220.     {
  221.       /* We can't shorten this! */
  222.       break;
  223.     }
  224.  
  225.       /* Shorten the pathname by one component and try again. */
  226.       zslash = strrchr (zpath, '/');
  227.       if (zslash == NULL)
  228.     {
  229.       /* Try the current directory.  We can open directories. */
  230.       zpath[0] = '.';
  231.       zpath[1] = '\0';
  232.     }
  233.       else if (zslash == zpath)
  234.     {
  235.       /* Try the root directory. */
  236.       zpath[0] = '/';
  237.       zpath[1] = '\0';
  238.     }
  239.       else
  240.     {
  241.       /* Chop off last path component. */
  242.       zslash[0] = '\0';
  243.     }
  244.     }
  245.   if (o == -1)
  246.     {
  247.       ulog (LOG_ERROR, "get_fs_usage: open (%s) failed: %s", zpath,
  248.         strerror (errno));
  249.       ubuffree (zpath);
  250.       return -1;
  251.     }
  252.   ubuffree (zpath);
  253.  
  254.   iret = disk_space (o, &cfree_blocks, &ctotal_blocks);
  255.   (void) close (o);
  256.   if (iret == -1)
  257.     {
  258.       ulog (LOG_ERROR, "get_fs_usage: disk_space failed: %s",
  259.         strerror (errno));
  260.       return -1;
  261.     }
  262.  
  263.   fsp->fsu_blocks = ctotal_blocks;
  264.   fsp->fsu_bfree = cfree_blocks;
  265.   fsp->fsu_bavail = cfree_blocks;
  266.     
  267.   /* QNX has no limit on the number of inodes.  Most inodes are stored
  268.      directly in the directory entry. */
  269.   fsp->fsu_files = -1;
  270.   fsp->fsu_ffree = -1;
  271. #endif /* STAT_DISK_SPACE */
  272.  
  273. #if STAT_USTAT
  274.   struct stat sstat;
  275.   struct ustat s;
  276.  
  277.   if (stat (path, &sstat) < 0
  278.       || ustat (sstat.st_dev, &s) < 0)
  279.     return -1;
  280.   fsp->fsu_blocks = -1;
  281.   fsp->fsu_bfree = s.f_tfree;
  282.   fsp->fsu_bavail = s.f_tfree;
  283.   fsp->fsu_files = -1;
  284.   fsp->fsu_ffree = -1;
  285. #endif
  286.  
  287. #if ! STAT_STATFS2_FS_DATA /* ! Ultrix */
  288. #if ! STAT_DISK_SPACE
  289. #if ! STAT_USTAT
  290. #if ! STAT_NONE
  291.   fsp->fsu_blocks = CONVERT_BLOCKS (fsd.f_blocks);
  292.   fsp->fsu_bfree = CONVERT_BLOCKS (fsd.f_bfree);
  293.   fsp->fsu_bavail = CONVERT_BLOCKS (fsd.f_bavail);
  294.   fsp->fsu_files = fsd.f_files;
  295.   fsp->fsu_ffree = fsd.f_ffree;
  296. #endif
  297. #endif
  298. #endif
  299. #endif
  300.  
  301.   return 0;
  302. }
  303.  
  304. #ifdef _AIX
  305. #ifdef _I386
  306. /* AIX PS/2 does not supply statfs.  */
  307.  
  308. int
  309. statfs (path, fsb)
  310.      char *path;
  311.      struct statfs *fsb;
  312. {
  313.   struct stat stats;
  314.   struct dustat fsd;
  315.  
  316.   if (stat (path, &stats))
  317.     return -1;
  318.   if (dustat (stats.st_dev, 0, &fsd, sizeof (fsd)))
  319.     return -1;
  320.   fsb->f_type   = 0;
  321.   fsb->f_bsize  = fsd.du_bsize;
  322.   fsb->f_blocks = fsd.du_fsize - fsd.du_isize;
  323.   fsb->f_bfree  = fsd.du_tfree;
  324.   fsb->f_bavail = fsd.du_tfree;
  325.   fsb->f_files  = (fsd.du_isize - 2) * fsd.du_inopb;
  326.   fsb->f_ffree  = fsd.du_tinode;
  327.   fsb->f_fsid.val[0] = fsd.du_site;
  328.   fsb->f_fsid.val[1] = fsd.du_pckno;
  329.   return 0;
  330. }
  331. #endif /* _I386 */
  332. #endif /* _AIX */
  333.